/**
 * Container
 * @param  {[type]} x [description]
 * @return {[type]}   [description]
 */
var Container = function (x) {
  this._value = x
}

Container.of = function (x) {
  return new Container(x)
}

Container.prototype.map = function (f) {
  return Container.of(f(this._value))
}

export.Container = Container

/**
 * IO
 * @param  {[type]} f [description]
 * @return {[type]}   [description]
 */
var IO = function (f) {
  this.__value = f
}

IO.of = function (x) {
  return new IO(function () {
    return x
  })
}

IO.prototype.map = function (f) {
  return new IO(_.compose(f, this.__value))
}

let data = new IO(() => window.localStorage['data'])
let head = (data) => data[0]
let prop = property => data => data[property]
let getName = data.map(head).map(prop('name'))

export.IO = IO

function applyMiddleware (...middlewares) {
  return (createStore) => (reducer, initialState, enhancer) {
    let store = createStore(reducer, initialState, enhancer)
    let dispatch = store.dispatch
    let chain = []

    let middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}
